/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package MessageIO;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketTimeoutException;
import java.util.StringTokenizer;

/**
 * PaketReceiver listens for DatagramPackets with messages from the
 * MessengerServer
 * @author Mark
 */
public class PacketReceiver implements Runnable
    {
    private MessageListener messageListen;//receives message
    private MulticastSocket multicastSocket;//receive broadcast messages
    private InetAddress group;//InetAdress of the multicast Server group
    private boolean keepListening;//turns false when want to be terminated

    /**
     * Creates a new PacketReceiver
     * @param listener receives message
     */
    public PacketReceiver(MessageListener listener)
        {
        super();
        messageListen = listener;
        try//connects MulticastSocket to multcast address and port
            {
            multicastSocket = new MulticastSocket(//makes a new multicast socket
                    SocketConstants.MULTICAST_LISTENING_PORT);
            group = InetAddress.getByName(SocketConstants.MULTICAST_ADDRESS);
            multicastSocket.joinGroup(group);
            multicastSocket.setSoTimeout(5000);
            keepListening = true;
            //set 5 seconds to timeout for packets
//            System.out.println("Packet Receiver Created");
            }
        catch (IOException io)
            {
            io.printStackTrace();
            }
        }

    /**
     * Listen for messages from multicast group
     */
    public void run()
        {
//        System.out.println("Running");
        while (keepListening)//listens for messages until terminated
            {
            byte[] buff = new byte[SocketConstants.MESSAGE_SIZE];//message buffer
//            System.out.println("Packt recieved" + new String(buff));
            DatagramPacket pack = new DatagramPacket(buff, SocketConstants.
                    MESSAGE_SIZE);//create DatagramPacket for incoming message
            try//receive new DatagramPacket
                {
                multicastSocket.receive(pack);
                }
            catch (SocketTimeoutException ste)
                {
                continue;//continue and keep listening
                }
            catch (IOException io)
                {
                io.printStackTrace();//break
                break;
                }

            String data = (new String(pack.getData())).trim();
            //Makes data and trims the white space
            StringTokenizer token = new StringTokenizer(data,
                    SocketConstants.MESSAGE_SEPERATOR);
            //Seperates into username and message
            if (token.countTokens() == 2)
                {
                messageListen.messageReceived(token.nextToken(),
                        token.nextToken());
                }
            else
                messageListen.messageReceived("", data);
            }

        try//leaves group and closes multicastsocket
            {
            multicastSocket.leaveGroup(group);
            multicastSocket.close();
            }
        catch (IOException io)
            {
            io.printStackTrace();
            }
        }

    /**
     * Stops listening for new messages
     */
    public void stopListening()
        {
        keepListening = false;
        }
    }
